package com.itheima.stock.service.Impl;

import com.google.common.collect.Lists;
import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBlockRtInfo;
import com.itheima.stock.pojo.StockMarketIndexInfo;
import com.itheima.stock.pojo.StockRtInfo;
import com.itheima.stock.service.StockTimerTaskService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.utils.ParseType;
import com.itheima.stock.utils.ParserStockInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service("stockTimerTaskService")
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private ParserStockInfoUtil parserStockInfoUtil;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override//大盘数据采集
    public void getInnerMarketInfo() {
        //组装动态url
        //http://hq.sinajs.cn/list=s_sh000001,s_sz399001
        String innerUrl = stockInfoConfig.getMarketUrl() + String.join(",", stockInfoConfig.getInner());
        //设置请求头信息
        HttpHeaders headers = new HttpHeaders();
        headers.add("Referer", "https://finance.sina.com.cn/stock/");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        //发起请求
        HttpEntity<Object> entity = new HttpEntity<>(headers);
        String result = restTemplate.postForObject(innerUrl, entity, String.class);
//        String result = restTemplate.getForObject(innerUrl, String.class);
        String reg = "var hq_str_(.+)=\"(.+)\";";
        //编译表达式,获得编译对象
        Pattern pattern = Pattern.compile(reg);
        //匹配字符串
        Matcher matcher = pattern.matcher(result);
        //收集大盘封装后后的对象
        ArrayList<StockMarketIndexInfo> list = new ArrayList<>();
        while (matcher.find()) {
            //获取大盘的id
            String marketCode = matcher.group(1);
            System.out.println(marketCode);
            //其它信息
            String other = matcher.group(2);
            String[] others = other.split(",");
            //大盘名称
            String marketName = others[0];
            //当前点
            BigDecimal curPoint = new BigDecimal(others[1]);
            //当前价格
            BigDecimal curPrice = new BigDecimal(others[2]);
            //涨跌率
            BigDecimal upDownRate = new BigDecimal(others[3]);
            //成交量
            Long tradeAmount = Long.valueOf(others[4]);
            //成交金额
            Long tradeVol = Long.valueOf(others[5]);
            //当前日期
            Date now = DateTimeUtil.getDateTimeWithoutSecond(DateTime.now()).toDate();
            //封装对象
            StockMarketIndexInfo stockMarketIndexInfo = StockMarketIndexInfo.builder().id(IdWorker.nextId(idWorker) + "")
                    .markName(marketName)
                    .tradeVolume(tradeVol)
                    .tradeAccount(tradeAmount)
                    .updownRate(upDownRate)
                    .curTime(now)
                    .curPoint(curPoint)
                    .currentPrice(curPrice)
                    .markId(marketCode)
                    .build();
            log.info(stockMarketIndexInfo.toString());
            list.add(stockMarketIndexInfo);

        }
        ;
        stockMarketIndexInfoMapper.insertBatch(list);

    }


    @Override//股票数据采集
    public void getStockRtIndex() {
        HttpHeaders headers = new HttpHeaders();
        //必须填写，否则数据采集不到
        headers.add("Referer", "https://finance.sina.com.cn/stock/");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        // 组装请求对象
        HttpEntity<Object> entity = new HttpEntity<>(headers);
        List<String> stockIds = stockBusinessMapper.getStockIds();
        stockIds = stockIds.stream().map(id -> {
            return id.startsWith("6") ? "sh" + id : "sz" + id;
        }).collect(Collectors.toList());
        Lists.partition(stockIds, 20).forEach(list -> {
            threadPoolTaskExecutor.execute(() -> {
                String stockUrl = stockInfoConfig.getMarketUrl() + String.join(",", list);
                String result = restTemplate.postForObject(stockUrl, entity, String.class);
                List<StockRtInfo> infos = parserStockInfoUtil.parser4StockOrMarketInfo(result, ParseType.ASHARE);
                log.info("数据量: {}", infos.size());
                stockRtInfoMapper.insertBatch(infos);
            });
        });
    }

    @Override//板块数据采集
    public void getStockSectorRtIndex() {
        HttpHeaders headers = new HttpHeaders();
        //必须填写，否则数据采集不到
        headers.add("Referer", "https://finance.sina.com.cn/stock/");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        // 组装请求对象
        HttpEntity<Object> entity = new HttpEntity<>(headers);
        String result = restTemplate.postForObject(stockInfoConfig.getBlockUrl(), entity, String.class);

        List<StockBlockRtInfo> infos = parserStockInfoUtil.parse4StockBlock(result);
        log.info("板块数据量：{}", infos.size());
        log.info("板块数据量：{}", infos);

        Lists.partition(infos, 20).forEach(list -> {
            //threadPoolTaskExecutor.execute(() -> {
                stockBlockRtInfoMapper.insertBatch(infos);
            });
        //});

    }
} 